import {contextBridge, ipcRenderer} from 'electron'
import type {NoteHistory, UserSettings} from '../src/types'
import {DirectoryTreeNode, FileIndexItem, OpenedFileRecord, OperationResult, TreeWalkOptions} from "../filespace/src";

// 暴露安全的 IPC 通信接口给渲染进程
contextBridge.exposeInMainWorld('bnote', {
  ready: {
    settings: () => ipcRenderer.invoke('ready:settings') as Promise<void>,
    fileSpace: () => ipcRenderer.invoke('ready:fileSpace') as Promise<void>
  },
  menus: {
    command: (key: string, x: number, y: number) => ipcRenderer.invoke('menus:command', key, x, y) as Promise<void>,
    onSetting: (cb: Function) => {
      ipcRenderer.on('menu:file:setting', (event) => {
        cb && cb()
      })
    }
  },
  settings: {
    load: () => ipcRenderer.invoke('settings:load') as Promise<UserSettings>,
    save: (settings: Partial<UserSettings>) => ipcRenderer.invoke('settings:save', settings) as Promise<void>
  },
  files: {
    getHistory: (fileId: string) => ipcRenderer.invoke('files:history:get', fileId) as Promise<NoteHistory[]>,
    selectPath: () => ipcRenderer.invoke('files:selectPath') as Promise<string | null>,
    create: (name: string, content?: string, parentId?: string) => ipcRenderer.invoke('files:create', name, content, parentId) as Promise<OperationResult<FileIndexItem>>,
    load: (fileId: string) => ipcRenderer.invoke('files:load', fileId) as Promise<string>,
    save: (fileId: string, content: string) => ipcRenderer.invoke('files:save', fileId, content) as Promise<boolean>,
    delete: (fileId: string) => ipcRenderer.invoke('files:delete', fileId) as Promise<boolean>,
    move: (fileId: string, parentId?: string) => ipcRenderer.invoke('files:move', fileId, parentId) as Promise<boolean>,
    addOrRemoveOpen: (fileId: string) => ipcRenderer.invoke('files:addOrRemoveOpen', fileId) as Promise<boolean>,
    openeds: () => ipcRenderer.invoke('files:openeds') as Promise<OpenedFileRecord[]>
  },
  dirs: {
    create: (name: string, parentId?: string) => ipcRenderer.invoke('dirs:create', name, parentId) as Promise<OperationResult<FileIndexItem>>,
    delete: (dirId: string) => ipcRenderer.invoke('dirs:delete', dirId) as Promise<boolean>,
    move: (dirId: string, parentId?: string) => ipcRenderer.invoke('dirs:move', dirId, parentId) as Promise<boolean>,
    childs: (dirId: string) => ipcRenderer.invoke('dirs:childs', dirId) as Promise<FileIndexItem[]>,
    root: () => ipcRenderer.invoke('dirs:root') as Promise<DirectoryTreeNode|null>,
    build: (startPath?: string, options?: TreeWalkOptions) => ipcRenderer.invoke('dirs:build', startPath, options) as Promise<DirectoryTreeNode|null>,
    tree: () => ipcRenderer.invoke('dirs:tree') as Promise<DirectoryTreeNode>,
    treeLazy: (dirId: string) => ipcRenderer.invoke('dirs:tree-lazy', dirId) as Promise<DirectoryTreeNode>,
    openedIds: () => ipcRenderer.invoke('dirs:openedIds') as Promise<string[]>
  },
  temps: {
    create: (name: string, parentId?: string, content?: string) => ipcRenderer.invoke('temps:create', name, parentId, content) as Promise<FileIndexItem|null>,
    load: (fileId: string) => ipcRenderer.invoke('temps:load', fileId) as Promise<string>,
    save: (fileId: string, content: string) => ipcRenderer.invoke('temps:save', fileId, content) as Promise<boolean>,
    delete: (fileId: string) => ipcRenderer.invoke('temps:delete', fileId) as Promise<boolean>,
    all: () => ipcRenderer.invoke('temps:all') as Promise<FileIndexItem[]>
  },
  contextmenus: {
    common: () => ipcRenderer.invoke('contextmenus:common') as Promise<void>,
    noteDirs: (item: DirectoryTreeNode) => ipcRenderer.invoke('contextmenus:note:dirs', item) as Promise<void>,
    noteFiles: (item: DirectoryTreeNode) => ipcRenderer.invoke('contextmenus:note:files', item) as Promise<void>,
    onNoteDirs: (cb: (command: ContextmenusNoteDirsCommand, item: DirectoryTreeNode) => void) => {
      ipcRenderer.on('contextmenus:note:dirs', (event, command, item: DirectoryTreeNode) => {
        cb && cb(command, item)
      })
    },
    onNoteFiles: (cb: (command: ContextmenusNoteFilesCommand, item: DirectoryTreeNode) => void) => {
      ipcRenderer.on('contextmenus:note:files', (event, command, item: DirectoryTreeNode) => {
        cb && cb(command, item)
      })
    }
  }
})
